#pragma once

#include <memory>
#include <string_view>
#include <zenoui/check_gl.hpp>
#include <zenox/glm.hpp>
#include <zenoui/Rect.hpp>
#include <functional>
#include <vector>
#include <map>

namespace zenoui {

struct FontData {
private:
    float font_width, font_height;
    char32_t char_min, char_max;
    int font_bitmap_width, font_bitmap_height;
    GLuint font_tex;

    struct Private;
    std::unique_ptr<Private> impl;

public:
    explicit FontData
    ( const char *font_path
    , bool enable_cache = false
    , bool enable_1bit = false
    , float font_height_ = 32.0f
    , char32_t char_min_ = 0x0
    , char32_t char_max_ = 0xffff
    );
    FontData(FontData &&) = delete;
    ~FontData();

    std::function<void(float, float)> prepare_draw_utf32(std::u32string_view text, float size) const;
    void draw_utf32(float x, float y, std::u32string_view text, float size) const;
    Rect predict_size_utf32(std::u32string_view text, float size) const;
    std::vector<std::vector<float>> scan_xypos_utf32(std::u32string_view text, float size) const;
    glm::vec2 font_size() const {
        return glm::vec2(font_width, font_height);
    }
};

struct FontCache {
    std::map<std::pair<int, std::string>, FontData, std::less<>> g_font_cache;

    FontCache();
    FontCache(FontCache &&) = delete;
    ~FontCache();

    FontData *get_font_by_name(std::string_view name, float size);
};

}
